package jddk;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.Socket;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.StringUtils;

import cn.hutool.core.util.ArrayUtil;

/**
 * 
 * socket client
 * 
 * @author GuoJian
 *
 */
public class SocketClient {

	private Socket client = null;

	public SocketClient(String ip, int port) {
		try {
			this.client = new Socket(ip, port);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public byte[] send(byte[] value) {
		try {
			OutputStream out = this.client.getOutputStream();
			InputStream in = this.client.getInputStream();
			//BufferedReader read = new BufferedReader(new InputStreamReader(), 8192 * 10);
			out.write(value);
			out.flush();

			if (!client.isOutputShutdown()) {
				client.shutdownOutput();
			}

			return IOUtils.toByteArray(in);
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				this.client.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public static byte[] buildRequestWithLength(byte[] requestByte) {
		int length = requestByte.length;
		byte[] lengthByte = StringUtils.leftPad(length + "", 8, '0').getBytes();
		return ArrayUtils.addAll(lengthByte, requestByte);
	}

	public static void main(String[] args) throws Exception {

		//byte[] result = new SocketClient("128.5.108.239", 8179).send("国检".getBytes());

		//System.out.println(new String(result));

		//fileTest("200000");

		//fileTest("100010");

		/*while (true) {
			try {
				fileTest("200000");
			} catch (Exception e) {
		
			}
			Thread.sleep(2000);
		}*/

		//GMzAdTXi//QOGRHoCU
		//qcjy();

		//CST_NM=%E5%80%99%E9%9B%B6%E5%85%AD

		//System.out.println(Charset.defaultCharset());

		//System.out.println(URLDecoder.decode("%E5%80%99%E9%9B%B6%E5%85%AD", Charset.forName("UTF-8")));

		//StringBuilder sb = new StringBuilder();

		//sb.append(getFixedLengthField(40, "候零六"));

		//System.out.println(sb.toString());

		//System.out.println(getFixedLengthField(40, "候零六"));

		//System.out.println(getFixedLengthField(40, "郭六二"));

		//dzjy();

		//qcjy();

		//myjh();

		//signjy();

		selectjy();

		//6217002870081615005                          

	}

	public static void selectjy() throws Exception {
		/*交易代码	6	char	Y	100010		
		服务代码	4	char	Y	0200		
		受卡机终端标识码	12	char	Y	交易发起圈存机编号		
		单位编码	20	Char	Y	银行方分给合作方的编号		
		第三方日期	8	char	Y	合作方交易日期		
		第三方时间	6	char	Y	合作方交易时间		
		第三方流水号	32	char	Y	合作方流水号，一天内不允许重复		
		MAC	16	char	N	全补空，16位长		*/

		StringBuilder header = new StringBuilder();
		header.append(getFixedLengthField(6, "300002"));//300002]100000
		header.append(getFixedLengthField(4, "0200"));//
		header.append(getFixedLengthField(12, "420607308001"));
		header.append(getFixedLengthField(20, "420137436000006"));//420167077000016 //420127145000010
		header.append(getFixedLengthField(8, "20210806"));
		header.append(getFixedLengthField(6, "111008"));
		header.append(getFixedLengthField(32, "12345678661"));
		header.append(getFixedLengthField(16, "176030913693"));
		String requestHeader = header.toString();
		System.out.println("requestHeader: " + requestHeader);

		/*交易帐号	28	Char	Y	借记卡卡号
		IC卡卡号	28	Char	Y	IC卡号
		密码验证标记	1	Char	Y	0 验证 1 不验证（暂时送1）
		密码	16	Char	N	暂时没用，保留
		二磁信息	50	Char	N	暂时没用，保留
		起始日期	8	Char	N	暂时没用，保留
		终止日期	8	Char	N	暂时没用，保留
		证件类型	1	char	N	
		证件号码	28	Char	Y	借记卡客户身份证号
		客户名称	40	Char	Y	借记卡客户姓名
		保留字段	48	Char	N	暂时没用，保留*/

		StringBuilder sb = new StringBuilder();

		//赵四三 身份证 420082196907246777签约账号6217002870081615005 学号 20210123456
		// 6236682870005834754         22318.84        1010420386197110093831          侯零六                              
		sb.append(getFixedLengthField(28, "6217002870081615005"));//主账号6236682870005834754
		sb.append(getFixedLengthField(28, "801608266"));//IC卡卡号 = 学工号
		sb.append(getFixedLengthField(1, "1"));
		sb.append(getFixedLengthField(16, ""));
		sb.append(getFixedLengthField(50, "1"));
		sb.append(getFixedLengthField(8, ""));
		sb.append(getFixedLengthField(8, ""));
		sb.append(getFixedLengthField(1, "1"));
		sb.append(getFixedLengthField(28, "420082196907246777"));//证件号码420917199105206714
		sb.append(getFixedLengthField(40, "赵四三"));
		sb.append(getFixedLengthField(48, "0"));

		String requestBody = sb.toString();
		System.out.println("requestBody: " + requestBody);

		byte[] encryptResponseBodyContent = DesUtil.encrypt(requestBody, "12345678");
		byte[] allentity = ArrayUtils.addAll(requestHeader.getBytes("GBK"), encryptResponseBodyContent);

		byte[] okEntity = buildRequestWithLength(allentity);
		//System.out.println(new String(okEntity));

		//byte[] result = new SocketClient("128.5.108.239", 8179).send(okEntity);
		byte[] result = new SocketClient("128.1.108.37", 1234).send(okEntity);

		//byte[] result = new SocketClient("128.1.108.215", 8179).send(okEntity);

		System.out.println(result.length);

		byte[] bodyResult = new byte[result.length - 112];

		ArrayUtil.copy(result, 112, bodyResult, 0, result.length - 112);

		byte[] deResult = DesUtil.decrypt(bodyResult, "12345678");

		System.out.println(IOUtils.toString(deResult, "GBK"));

	}

	public static void signjy() throws Exception {
		/*交易代码	6	char	Y	100010		
		服务代码	4	char	Y	0200		
		受卡机终端标识码	12	char	Y	交易发起圈存机编号		
		单位编码	20	Char	Y	银行方分给合作方的编号		
		第三方日期	8	char	Y	合作方交易日期		
		第三方时间	6	char	Y	合作方交易时间		
		第三方流水号	32	char	Y	合作方流水号，一天内不允许重复		
		MAC	16	char	N	全补空，16位长		*/

		StringBuilder header = new StringBuilder();
		header.append(getFixedLengthField(6, "100050"));//功能号
		header.append(getFixedLengthField(4, "0200"));//功能号
		header.append(getFixedLengthField(12, "420607308001"));
		header.append(getFixedLengthField(20, "420646043000008"));//420137436000006 //420167077000016
		header.append(getFixedLengthField(8, "20210806"));
		header.append(getFixedLengthField(6, "111008"));
		header.append(getFixedLengthField(32, "12345678661"));
		header.append(getFixedLengthField(16, ""));
		String requestHeader = header.toString();
		System.out.println("requestHeader: " + requestHeader);

		/*银行卡账号	40	Char	Y	银行卡账号
		学工号	30	Char	Y	学工号
		学生姓名	50	Char	Y	学生姓名
		学生手机号	11	Char	N	学生手机号
		身份证号	120	Char	Y	学生身份证号
		标记	1	Char	Y	签约/修改/解约标志
		保留字段1	3	Char	N	暂时没用，保留*/

		StringBuilder sb = new StringBuilder();

		//赵四三 身份证 420082196907246777 签约账号 6217002870081615005 学号 20210123456
		//郭六二 身份证 420917199105206714 卡号:6217002660007873923
		sb.append(getFixedLengthField(40, "62170028700816150015"));//主账号6236682870005834754
		sb.append(getFixedLengthField(30, "20210123456"));//IC卡卡号
		sb.append(getFixedLengthField(50, "赵四三"));
		sb.append(getFixedLengthField(11, "17603091637"));
		sb.append(getFixedLengthField(120, "420082196907246777"));//证件号码420917199105206714
		sb.append(getFixedLengthField(1, "1"));
		sb.append(getFixedLengthField(3, ""));

		String requestBody = sb.toString();
		System.out.println("requestBody: " + requestBody);

		byte[] encryptResponseBodyContent = DesUtil.encrypt(requestBody, "12345678");
		byte[] allentity = ArrayUtils.addAll(requestHeader.getBytes("GBK"), encryptResponseBodyContent);

		byte[] okEntity = buildRequestWithLength(allentity);
		//System.out.println(new String(okEntity));

		//byte[] result = new SocketClient("128.5.108.239", 8179).send(okEntity);
		//byte[] result = new SocketClient("128.1.108.37", 1234).send(okEntity);

		byte[] result = new SocketClient("128.1.108.215", 8179).send(okEntity);
		//
		byte[] bodyResult = new byte[result.length - 112];

		ArrayUtil.copy(result, 112, bodyResult, 0, result.length - 112);

		byte[] deResult = DesUtil.decrypt(bodyResult, "12345678");

		System.out.println(IOUtils.toString(deResult, "GBK"));

	}

	public static void qcjy() throws IOException, UnsupportedEncodingException {
		/*String entityBody = FileUtils.readFileToString(new File("d:/jszx100010"));
		System.out.println(entityBody.length());
		String requestHeader = entityBody.substring(0, 104);
		System.out.println("requestHeader: " + requestHeader);*/

		/*交易代码	6	char	Y	100010		
		服务代码	4	char	Y	0200		
		受卡机终端标识码	12	char	Y	交易发起圈存机编号		
		单位编码	20	Char	Y	银行方分给合作方的编号		
		第三方日期	8	char	Y	合作方交易日期		
		第三方时间	6	char	Y	合作方交易时间		
		第三方流水号	32	char	Y	合作方流水号，一天内不允许重复		
		MAC	16	char	N	全补空，16位长		*/

		StringBuilder header = new StringBuilder();
		header.append(getFixedLengthField(6, "100010"));//功能号
		header.append(getFixedLengthField(4, "0200"));//功能号
		header.append(getFixedLengthField(12, "420607308001"));
		header.append(getFixedLengthField(20, "420137436000006"));//单位编号
		header.append(getFixedLengthField(8, "20210914"));
		header.append(getFixedLengthField(6, "111008"));
		header.append(getFixedLengthField(32, "12345678116"));
		header.append(getFixedLengthField(16, ""));

		String requestHeader = header.toString();
		System.out.println("requestHeader: " + requestHeader);

		/*功能号	1	Char	N	保留字段，圈存填1
		主账号	28	Char	Y	借记卡卡号
		IC卡卡号	28	Char	Y	IC卡号
		密码验证标记	1	Char	Y	0 验证 1 不验证（暂时送1）
		密码	16	Char	N	暂时没用，保留
		二磁信息	50	Char	N	暂时没用，保留
		交易金额	16	Char	Y	圈存金额
		IC卡有效期	8	Char	N	IC卡有效期
		清算日期	8	Char	N	暂时没用，保留
		帐户标识	28	Char	N	暂时没用，保留
		证件类型	1	char	N	
		证件号码	28	Char	Y	借记卡客户身份证号
		客户名称	40	Char	Y	借记卡客户姓名
		保留字段1	3	Char	N	暂时没用，保留*/

		StringBuilder sb = new StringBuilder();

		//赵四三 身份证 420082196907246777签约账号6217002870081615005 学号 20210123456
		sb.append(getFixedLengthField(1, "1"));//功能号
		sb.append(getFixedLengthField(28, "6236682870005834754"));//主账号6236682870005834754 //
		sb.append(getFixedLengthField(28, "801608"));//IC卡卡号
		sb.append(getFixedLengthField(1, "1"));
		sb.append(getFixedLengthField(16, ""));//密码
		sb.append(getFixedLengthField(50, ""));//二磁信息
		sb.append(getFixedLengthField(16, "1000"));//圈存金额
		sb.append(getFixedLengthField(8, ""));//IC卡有效期
		sb.append(getFixedLengthField(8, ""));//清算日期
		sb.append(getFixedLengthField(28, ""));//帐户标识
		sb.append(getFixedLengthField(1, ""));
		sb.append(getFixedLengthField(28, "420082196907246777"));//证件号码420917199105206714 //420082196907246777
		sb.append(getFixedLengthField(40, "赵四三"));
		sb.append(getFixedLengthField(3, ""));

		String requestBody = sb.toString();
		System.out.println("requestBody: " + requestBody);

		byte[] encryptResponseBodyContent = DesUtil.encrypt(requestBody, "12345678");
		byte[] allentity = ArrayUtils.addAll(requestHeader.getBytes("GBK"), encryptResponseBodyContent);

		byte[] okEntity = buildRequestWithLength(allentity);
		//System.out.println(new String(okEntity));

		//byte[] result = new SocketClient("128.5.108.239", 8179).send(okEntity);
		//byte[] result = new SocketClient("128.1.108.37", 1234).send(okEntity);

		byte[] result = new SocketClient("128.1.108.215", 8179).send(okEntity);
		//

		System.out.println(result.length);

		byte[] bodyResult = new byte[result.length - 112];

		ArrayUtil.copy(result, 112, bodyResult, 0, result.length - 112);

		byte[] deResult = DesUtil.decrypt(bodyResult, "12345678");

		System.out.println(IOUtils.toString(deResult, "GBK"));

	}

	protected static String getFixedLengthField(int length, String value) {
		try {
			String newValue = ObjectUtils.toString(value);
			byte[] valueByte = newValue.getBytes("GBK");
			if (valueByte.length < length) {
				while (newValue.getBytes("GBK").length < length) {
					newValue = newValue + " ";
				}
				return newValue;
			} else {
				return new String(valueByte, 0, length, "GBK");
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return StringUtils.EMPTY;
	}

	private static void dzjy() throws UnsupportedEncodingException, IOException {
		String jydm = "100030";
		String fwdm = "0200";
		String zdbsm = "420147237004";
		//420167077000016
		String dwbm = "420167077000016     ";
		String dsfrq = "20210315";
		String dsfsj = "141501";
		String dsflsh = "20210315141501000000000000000001";
		String mac = "162930          ";

		String dzflag = "2";
		String date = "20210514";
		String blzd = getStrByLength(119, "");

		String reqHeader = jydm + fwdm + zdbsm + dwbm + dsfrq + dsfsj + dsflsh + mac;

		String reqbody = dzflag + date + blzd;
		byte[] encryptResponseBodyContent = DesUtil.encrypt(reqbody, "12345678");
		byte[] reqAll = ArrayUtils.addAll(reqHeader.getBytes("GBK"), encryptResponseBodyContent);

		byte[] okEntity = buildRequestWithLength(reqAll);

		//byte[] result = new SocketClient("128.5.108.239", 8179).send(okEntity);
		byte[] result = new SocketClient("128.1.108.215", 8179).send(okEntity);
		byte[] bodyResult = new byte[result.length - 112];

		ArrayUtil.copy(result, 112, bodyResult, 0, result.length - 112);

		byte[] deResult = DesUtil.decrypt(bodyResult, "12345678");

		System.out.println(IOUtils.toString(deResult, "GBK"));

		///home/ap/hbp5dsdf/card_files/20210514/420701233/JH_YSYZ_20210514.txt
		///home/ap/hbp5dsdf/card_files/20210514/420701233/JH_JSYZ_20210514.txt
		//读不到这个文件

	}

	public static void fileTest(String type) throws IOException, UnsupportedEncodingException {

		String entityBody = FileUtils.readFileToString(new File("d:/jszx" + type + ""));

		System.out.println(entityBody.length());

		String requestHeader = entityBody.substring(0, 104);

		System.out.println("requestHeader: " + requestHeader);

		String requestBody = entityBody.substring(104, entityBody.length());

		System.out.println("requestBody: " + requestBody);

		//GMzAdTXi//ZxEXzkKz//QPyEFtEB//SQCgDQJn
		byte[] encryptResponseBodyContent = DesUtil.encrypt(requestBody, "SQCgDQJn");

		byte[] allentity = ArrayUtils.addAll(requestHeader.getBytes("GBK"), encryptResponseBodyContent);

		byte[] okEntity = buildRequestWithLength(allentity);
		//System.out.println(new String(okEntity));

		//byte[] result = new SocketClient("128.5.108.239", 8179).send(okEntity);
		//byte[] result = new SocketClient("128.1.108.37", 11010).send(okEntity);
		//byte[] result = new SocketClient("128.1.108.37", 1235).send(okEntity);
		byte[] result = new SocketClient("128.1.108.215", 8179).send(okEntity);

		byte[] bodyResult = new byte[result.length - 112];

		ArrayUtil.copy(result, 112, bodyResult, 0, result.length - 112);

		//QPyEFtEB
		byte[] deResult = DesUtil.decrypt(bodyResult, "SQCgDQJn");

		System.out.println(new String(deResult, "GBK"));

		//YDC此客户不存在#106001#FBASCST1##          20210423    
		//999此客户不存在#106001#FBASCST1##          20210423           
	}

	public static void myjh() throws IOException {

		StringBuilder header = new StringBuilder();
		header.append(getFixedLengthField(6, "200000"));
		header.append(getFixedLengthField(4, "0200"));
		header.append(getFixedLengthField(12, "420147237004"));
		header.append(getFixedLengthField(20, "420147237000017"));
		header.append(getFixedLengthField(8, "20210521"));
		header.append(getFixedLengthField(6, "111008"));
		header.append(getFixedLengthField(32, "1234567890"));
		header.append(getFixedLengthField(16, ""));

		StringBuilder reqbody = new StringBuilder();
		reqbody.append(getFixedLengthField(1, "1"));
		reqbody.append(getFixedLengthField(127, ""));

		byte[] encryptResponseBodyContent = DesUtil.encrypt(reqbody.toString(), "12345678");
		byte[] allentity = ArrayUtils.addAll(header.toString().getBytes("GBK"), encryptResponseBodyContent);

		byte[] okEntity = buildRequestWithLength(allentity);

		byte[] result = new SocketClient("128.5.108.239", 8179).send(okEntity);
		//byte[] result = new SocketClient("128.1.108.215", 8179).send(reqAll);

		byte[] bodyResult = new byte[result.length - 112];

		ArrayUtil.copy(result, 112, bodyResult, 0, result.length - 112);

		byte[] deResult = DesUtil.decrypt(bodyResult, "12345678");

		System.out.println(new String(deResult, "GBK"));
	}

	public static String getStrByLength(int length, String value) {
		return String.format("%-" + length + "s", value);
	}

}
